1 using UnityEngine;
2 using
System.Collections;
3 using
System.Collections.Generic;
4
5
6 public
class Go : MonoBehaviour
7 {
8     
// defaults used for all tweens/properties that are not explicitly set
9     
public static GoEaseType defaultEaseType = GoEaseType.Linear;
10     
public static GoLoopType defaultLoopType = GoLoopType.RestartFromBeginning;
11     
public static GoUpdateType defaultUpdateType = GoUpdateType.Update;
12
13     
// defines what we should do in the event that a TweenProperty is added and an already existing tween has the same
14     
// property and target
15     
public static GoDuplicatePropertyRuleType duplicatePropertyRule = GoDuplicatePropertyRuleType.None;
16     
public static GoLogLevel logLevel = GoLogLevel.Warn;
17
18     
// validates that the target object still exists each tick of the tween. NOTE: it is recommended
19     
// that you just properly remove your tweens before destroying any objects even though this might destroy them for you
20     
public static bool validateTargetObjectsEachTick = true;
21
22     
// Used to stop instances being created while the application is quitting
23     
private static bool _applicationIsQuitting = false;
24
25     
private static List<AbstractGoTween> _tweens = new List<AbstractGoTween>(); // contains Tweens, TweenChains and TweenFlows
26     
private bool _timeScaleIndependentUpdateIsRunning;
27
28     
// only one Go can exist
29     
static Go _instance = null;
30     
public static Go instance
31     {
32         
get
33         {
34             
// Don't allow new instances to be created when the application is quitting to avoid the GOKit object never being destroyed.
35             
// These dangling instances can't be found with FindObjectOfType and so you'd get multiple instances in a scene.
36             
if( !_instance && !_applicationIsQuitting )
37             {
38                 
// check if there is a GO instance already available in the scene graph
39                 _instance = FindObjectOfType(
typeof( Go ) ) as Go;
40
41                 
// possible Unity bug with FindObjectOfType workaround
42                 
//_instance = FindObjectOfType( typeof( Go ) ) ?? GameObject.Find( "GoKit" ).GetComponent<Go>() as Go;
43
44                 
// nope, create a new one
45                 
if( !_instance )
46                 {
47                     
var obj = new GameObject( "GoKit" );
48                     _instance = obj.AddComponent<Go>();
49                     DontDestroyOnLoad( obj );
50                 }
51             }
52
53             
return _instance;
54         }
55     }

56
57
58     ///
<summary>
59     ///
loops through all the Tweens and updates any that are of updateType. If any Tweens are complete
60     ///
(the update call will return true) they are removed.
61     ///
</summary>
62     
private void handleUpdateOfType( GoUpdateType updateType, float deltaTime )
63     {
64         
// loop backwards so we can remove completed tweens
65         
for( var i = _tweens.Count - 1; i >= 0; --i )
66         {
67             
var t = _tweens[i];
68
69             
if( t.state == GoTweenState.Destroyed )
70             {
71                 
// destroy method has been called
72                 removeTween( t );
73             }
74             
else
75             {
76                 
// only process tweens with our update type that are running
77                 
if( t.updateType == updateType && t.state == GoTweenState.Running && t.update( deltaTime * t.timeScale ) )
78                 {
79                     
// tween is complete if we get here. if destroyed or set to auto remove kill it
80                     
if( t.state == GoTweenState.Destroyed || t.autoRemoveOnComplete )
81                     {
82                         removeTween( t );
83                         t.destroy();
84                     }
85                 }
86             }
87         }
88     }
89
90
91     
#region Monobehaviour
92
93     
private void Update()
94     {
95         
if( _tweens.Count == 0 )
96             
return;
97
98         handleUpdateOfType( GoUpdateType.Update, Time.deltaTime );
99     }
100
101
102     
private void LateUpdate()
103     {
104         
if( _tweens.Count == 0 )
105             
return;
106
107         handleUpdateOfType( GoUpdateType.LateUpdate, Time.deltaTime );
108     }
109
110
111     
private void FixedUpdate()
112     {
113         
if( _tweens.Count == 0 )
114             
return;
115
116         handleUpdateOfType( GoUpdateType.FixedUpdate, Time.deltaTime );
117     }
118
119
120     
private void OnApplicationQuit()
121     {
122         _instance =
null;
123         Destroy( gameObject );
124         _applicationIsQuitting =
true;
125     }
126
127     
#endregion
128
129
130     ///
<summary>
131     ///
this only runs as needed and handles time scale independent Tweens
132     ///
</summary>
133     
private IEnumerator timeScaleIndependentUpdate()
134     {
135         _timeScaleIndependentUpdateIsRunning =
true;
136         
var time = Time.realtimeSinceStartup;
137
138         
while( _tweens.Count > 0 )
139         {
140             
var elapsed = Time.realtimeSinceStartup - time;
141             time = Time.realtimeSinceStartup;
142
143             
// update tweens
144             handleUpdateOfType( GoUpdateType.TimeScaleIndependentUpdate, elapsed );
145
146             
yield return null;
147         }
148
149         _timeScaleIndependentUpdateIsRunning =
false;
150     }

151
152
153     ///
<summary>
154     ///
checks for duplicate properties. if one is found and the DuplicatePropertyRuleType is set to
155     ///
DontAddCurrentProperty it will return true indicating that the tween should not be added.
156     ///
this only checks tweens that are not part of an AbstractTweenCollection
157     ///
</summary>
158     
private static bool handleDuplicatePropertiesInTween( GoTween tween )
159     {
160         
// first fetch all the current tweens with the same target object as this one
161         
var allTweensWithTarget = tweensWithTarget( tween.target );
162
163         
// store a list of all the properties in the tween
164         
var allProperties = tween.allTweenProperties();
165
166         
// TODO: perhaps only perform the check on running Tweens?
167
168         
// loop through all the tweens with the same target
169         
foreach( var tweenWithTarget in allTweensWithTarget )
170         {
171             
// loop through all the properties in the tween and see if there are any dupes
172             
foreach( var tweenProp in allProperties )
173             {
174                 warn(
"found duplicate TweenProperty {0} in tween {1}", tweenProp, tween );
175
176                 
// check for a matched property
177                 
if( tweenWithTarget.containsTweenProperty( tweenProp ) )
178                 {
179                     
// handle the different duplicate property rules
180                     
if( duplicatePropertyRule == GoDuplicatePropertyRuleType.DontAddCurrentProperty )
181                     {
182                         
return true;
183                     }
184                     
else if( duplicatePropertyRule == GoDuplicatePropertyRuleType.RemoveRunningProperty )
185                     {
186                         
// TODO: perhaps check if the Tween has any properties left and remove it if it doesnt?
187                         tweenWithTarget.removeTweenProperty( tweenProp );
188                     }
189
190                     
return false;
191                 }
192             }
193         }
194
195         
return false;
196     }
197
198
199     
#region Logging
200
201     ///
<summary>
202     ///
logging should only occur in the editor so we use a conditional
203     ///
</summary>
204     
[System.Diagnostics.Conditional( "UNITY_EDITOR" )]
205     
private static void log( object format, params object[] paramList )
206     {
207         
if( format is string )
208             Debug.Log(
string.Format( format as string, paramList ) );
209         
else
210             Debug.Log( format );
211     }
212
213
214     
[System.Diagnostics.Conditional( "UNITY_EDITOR" )]
215     
public static void warn( object format, params object[] paramList )
216     {
217         
if( logLevel == GoLogLevel.None || logLevel == GoLogLevel.Info )
218             
return;
219
220         
if( format is string )
221             Debug.LogWarning(
string.Format( format as string, paramList ) );
222         
else
223             Debug.LogWarning( format );
224     }
225
226
227     
[System.Diagnostics.Conditional( "UNITY_EDITOR" )]
228     
public static void error( object format, params object[] paramList )
229     {
230         
if( logLevel == GoLogLevel.None || logLevel == GoLogLevel.Info || logLevel == GoLogLevel.Warn )
231             
return;
232
233         
if( format is string )
234             Debug.LogError(
string.Format( format as string, paramList ) );
235         
else
236             Debug.LogError( format );
237     }
238
239     
#endregion
240
241
242     
#region public API
243
244     ///
<summary>
245     ///
helper function that creates a "to" Tween and adds it to the pool
246     ///
</summary>
247     
public static GoTween to( object target, float duration, GoTweenConfig config )
248     {
249         config.setIsTo();
250         
var tween = new GoTween( target, duration, config );
251         addTween( tween );
252
253         
return tween;
254     }

255
256
257     ///
<summary>
258     ///
helper function that creates a "from" Tween and adds it to the pool
259     ///
</summary>
260     
public static GoTween from( object target, float duration, GoTweenConfig config )
261     {
262         config.setIsFrom();
263         
var tween = new GoTween( target, duration, config );
264         addTween( tween );
265
266         
return tween;
267     }

268
269
270     ///
<summary>
271     ///
adds an AbstractTween (Tween, TweenChain or TweenFlow) to the current list of running Tweens
272     ///
</summary>
273     
public static void addTween( AbstractGoTween tween )
274     {
275         
// early out for invalid items
276         
if( !tween.isValid() )
277             
return;
278
279         
// dont add the same tween twice
280         
if( _tweens.Contains( tween ) )
281             
return;
282
283         
// check for dupes and handle them before adding the tween. we only need to check for Tweens
284         
if( duplicatePropertyRule != GoDuplicatePropertyRuleType.None && tween is GoTween )
285         {
286             
// if handleDuplicatePropertiesInTween returns true it indicates we should not add this tween
287             
if( handleDuplicatePropertiesInTween( tween as GoTween ) )
288                 
return;
289
290             
// if we became invalid after handling dupes dont add the tween
291             
if( !tween.isValid() )
292                 
return;
293         }
294
295         _tweens.Add( tween );
296
297         
// enable ourself if we are not enabled
298         
if( !instance.enabled ) // purposely using the static instace property just once for initialization
299             _instance.enabled =
true;
300
301         
// if the Tween isn't paused and it is a "from" tween jump directly to the start position
302         
if( tween is GoTween && ((GoTween)tween).isFrom && tween.state != GoTweenState.Paused )
303             tween.update(
0 );
304
305         
// should we start up the time scale independent update?
306         
if( !_instance._timeScaleIndependentUpdateIsRunning && tween.updateType == GoUpdateType.TimeScaleIndependentUpdate )
307             _instance.StartCoroutine( _instance.timeScaleIndependentUpdate() );
308
309 #
if UNITY_EDITOR
310         _instance.gameObject.name =
string.Format( "GoKit ({0} tweens)", _tweens.Count );
311 #endif
312     }

313
314
315     ///
<summary>
316     ///
removes the Tween returning true if it was removed or false if it was not found
317     ///
</summary>
318     
public static bool removeTween( AbstractGoTween tween )
319     {
320         
if( _tweens.Contains( tween ) )
321         {
322             _tweens.Remove( tween );
323
324 #
if UNITY_EDITOR
325         
if( _instance != null && _tweens != null )
326             _instance.gameObject.name =
string.Format( "GoKit ({0} tweens)", _tweens.Count );
327 #endif
328
329             
if( _instance != null && _tweens.Count == 0 )
330             {
331                 
// disable ourself if we have no more tweens
332                 _instance.enabled =
false;
333             }
334
335             
return true;
336         }
337
338         
return false;
339     }

340
341
342     ///
<summary>
343     ///
returns a list of all Tweens, TweenChains and TweenFlows with the given id
344     ///
</summary>
345     
public static List<AbstractGoTween> tweensWithId( int id )
346     {
347         List<AbstractGoTween> list =
null;
348
349         
foreach( var tween in _tweens )
350         {
351             
if( tween.id == id )
352             {
353                 
if( list == null )
354                     list =
new List<AbstractGoTween>();
355                 list.Add( tween );
356             }
357         }
358
359         
return list;
360     }

361
362
363     ///
<summary>
364     ///
returns a list of all Tweens with the given target. TweenChains and TweenFlows can optionally
365     ///
be traversed and matching Tweens returned as well.
366     ///
</summary>
367     
public static List<GoTween> tweensWithTarget( object target, bool traverseCollections = false )
368     {
369         List<GoTween> list =
new List<GoTween>();
370
371         
foreach( var item in _tweens )
372         {
373             
// we always check Tweens so handle them first
374             
var tween = item as GoTween;
375             
if( tween != null && tween.target == target )
376                 list.Add( tween );
377
378             
// optionally check TweenChains and TweenFlows. if tween is null we have a collection
379             
if( traverseCollections && tween == null )
380             {
381                 
var tweenCollection = item as AbstractGoTweenCollection;
382                 
if( tweenCollection != null )
383                 {
384                     
var tweensInCollection = tweenCollection.tweensWithTarget( target );
385                     
if( tweensInCollection.Count > 0 )
386                         list.AddRange( tweensInCollection );
387                 }
388             }
389         }
390
391         
return list;
392     }

393
394
395     ///
<summary>
396     ///
kills all tweens with the given target by calling the destroy method on each one
397     ///
</summary>
398     
public static void killAllTweensWithTarget( object target )
399     {
400         
foreach( var tween in tweensWithTarget( target, true ) )
401             tween.destroy();
402     }
403
404     
#endregion
405
406 }



Trò chơi Angry Birds trong UNITY Engine 31.679 lượt xem

Gõ tìm kiếm nhanh...